function splitStatements(input) {
  let statements = [];
  let current = '';
  let level = 0;
  for (let c of input.replace(/\n/g, ' ')) {
    if (c === '{') level++;
    else if (c === '}') level--;
    if (c === ';' && level === 0) {
      statements.push(current.trim());
      current = '';
    } else {
      current += c;
    }
  }
  if (current.trim()) statements.push(current.trim());
  return statements;
}

export default async function executeScript(input) {
  const statements = splitStatements(input);
  for (const stmt of statements) {
    await executeStatement(stmt);
  }
}

async function executeStatement(stmt) {
  if (!stmt) return;
  if (stmt.startsWith('set')) {
    await handleSet(stmt);
  } else if (stmt.startsWith('while')) {
    await handleWhileLoop(stmt);
  } else if (stmt.startsWith('if')) {
    await handleIfStatement(stmt);
  } else {
    throw new Error(`Unknown statement: ${stmt}`);
  }
}

async function handleSet(stmt) {
  const match = stmt.match(/^set\s+(?:\[([^\]]+)\]|(\S+))\s+(.+)$/);
  if (!match) throw new Error(`Invalid set statement: ${stmt}`);
  const key = (match[1] || match[2]).trim();
  const value = parseValue(match[3].trim());

  await setValueByUnifiedKey(key,value,"int")

}

function parseValue(valueStr) {
  const num = Number(valueStr);
  return isNaN(num) ? valueStr : num;
}

async function handleWhileLoop(stmt) {
  const match = stmt.match(/^while\s*\(([^)]*)\)\s*{([^}]*)}/);
  if (!match) throw new Error(`Invalid while loop: ${stmt}`);
  const conditionExpr = match[1].trim();
  const body = match[2].trim();

  while (true) {
    const conditionResult = await evaluateCondition(conditionExpr);
    if (!conditionResult) break;
    await executeScript(body);
    await new Promise(resolve => setTimeout(resolve, 1000));
  }
}

async function handleIfStatement(stmt) {
  const match = stmt.match(/^if\s*\(([^)]*)\)\s*{([^}]*)}/);
  if (!match) throw new Error(`Invalid if statement: ${stmt}`);
  const conditionExpr = match[1].trim();
  const body = match[2].trim();

  const conditionResult = await evaluateCondition(conditionExpr);
  if (conditionResult) {
    await executeScript(body);
  }
}

async function evaluateCondition(expr) {
  // 正则表达式解析（修正索引错误）
  const match = expr.match(/^get\s+(?:\[([^\]]+)\]|(\S+))\s*(<|>|=|<=|>=|==| )\s*(-?\d+\.?\d*)$/i);
  if (!match) throw new Error(`Invalid evaluateCondition expr: ${expr}`);

  // 正确获取各部分参数
  const key = (match[1] || match[2]).trim(); // 处理带[]和不带[]的key
  const cmp = match[3].trim();               // 比较运算符
  const rightValue = parseValue(match[4]);   // 右边数值


  // 获取并转换左值
  const leftValue = await getValueByUnifiedKey(key);
  const numLeft = Number(leftValue);
  const numRight = Number(rightValue);

  // console.log("numLeft: " + numLeft + " numRight: " + numRight)

  // 类型检查
  if (isNaN(numLeft) || isNaN(numRight)) {
    throw new Error(`Invalid number comparison: ${leftValue} ${cmp} ${rightValue}`);
  }

  // 执行比较逻辑
  switch (cmp) {
    case '<':  return numLeft < numRight;
    case '>':  return numLeft > numRight;
    case '<=': return numLeft <= numRight;
    case '>=': return numLeft >= numRight;
    case '':  // 兼容 = 和 ==
    case '=':  // 兼容 = 和 ==
    case '==': return numLeft === numRight;
    default:
      throw new Error(`Unsupported comparator: ${cmp}`);
  }
}

// http.js - HTTP请求封装模块
class HttpService {
  constructor(baseURL) {
    this.baseURL = baseURL;
  }

  async request(method, endpoint, data = null) {
    const url = `${this.baseURL}${endpoint}`;
    const config = {
      method: method.toUpperCase(),
      headers: {
        'Content-Type': 'application/json',
      }
    };

    if (data) {
      config.body = JSON.stringify(data);
    }
    console.log("endpoint: " + endpoint)
    console.log("config.body: " + config.body)

    try {
      const response = await fetch(url, config);
      // console.log("response.status: " + response.status)
      // console.log("response.statusText: " + response.statusText)
      console.log("response.ok: " + response.ok)
      // console.log("response.text: " + response.text)
      // console.log("response.json: " + JSON.stringify(response.json()))
      // console.log("response.headers: " + response.headers)
      // console.log("response.headers.get: " + response.headers.get)

      return Promise.resolve(response); // 修复bug，确保返回Promise值
    } catch (error) {
      console.error(`HTTP request failed: ${error.message}`);
      return Promise.reject(error); // 确保错误也返回Promise
    }
  }

  setAuthToken(token) {
    this.token = token;
  }

  async get(endpoint, params) {
    const query = new URLSearchParams(params).toString();
    return this.request('GET', `${endpoint}?${query}`);
  }

  async post(endpoint, data) {
    return this.request('POST', endpoint, data);
  }

  async post_params(endpoint, params) {
    const query = new URLSearchParams(params).toString();
    return this.request('POST', `${endpoint}?${query}`);
  }
}

const model_backend_url = 'http://10.149.158.72:8081'
const opcua_backend_url = 'http://10.149.158.72:8080'
// 初始化HTTP服务（请替换为实际API地址）
const http = new HttpService(model_backend_url);
const http_opcua = new HttpService(opcua_backend_url);


// 改造后的业务方法
async function setValueByUnifiedKey(unifiedKey, value, type) {
  try {
    console.log("set unifiedKey: " + unifiedKey + " value: " + value)
    let resultObj = await http.get('/v1/profiles/' + unifiedKey, {});
    // 取出resultObj的body的值
    resultObj = await resultObj.json()
    console.log("resultObj: " + JSON.stringify(resultObj))


    if( !resultObj["characteristicNodeId"] || resultObj["characteristicNodeId"] == null){
      let result = await http.post('/v1/profiles/' + unifiedKey + "/value/" + value, {});
      result = await result.json()
      console.info("setValueByUnifiedKey 物模型 Result: "  + JSON.stringify(result))
      return value
    }
    // OPC-UA的value
    else{
      let keys= ['node_id', 'value' , 'type']
      let values= [resultObj["characteristicNodeId"], value , type]
      let result = await http_opcua.post_params('/set', Object.fromEntries(keys.map((_, i) => [keys[i], values[i]])))
      result = await result.json()
      console.info("setValueByUnifiedKey opc Result: " + JSON.stringify(result))
      return result
    }
  } catch (error) {
    console.error(`Set失败: ${unifiedKey}`, error);
    throw new Error(`无法设置设备值: ${unifiedKey}`);
  }
}

async function getValueByUnifiedKey(unifiedKey) {
  try {
    console.info("get unifiedKey: " + unifiedKey)
    let resultObj = await http.get('/v1/profiles/' + unifiedKey, {});
    // 打印resultObj
    resultObj = await resultObj.json()
    console.log("resultObj: " + JSON.stringify(resultObj))

    if( !resultObj["characteristicNodeId"] || resultObj["characteristicNodeId"] == null){
      console.info("getValueByUnifiedKey 物模型  Result: " + resultObj["value"])
      return resultObj["value"]
    }
    // OPC-UA的value
    else{
      let keys= ['node_id']
      let values= [resultObj["characteristicNodeId"]]
      let opcResult = await http_opcua.get('/get', Object.fromEntries(keys.map((_, i) => [keys[i], values[i]])))
      opcResult = await opcResult.json()
      console.info("getValueByUnifiedKey opc Result: " + JSON.stringify(opcResult))
      return opcResult["value"]
    }
  } catch (error) {
    console.error(`Get失败: ${unifiedKey}`, error);
    throw new Error(`无法获取设备值: ${unifiedKey}`);
  }
}

/* 使用示例 */
const testScript = `
  set DNAProductionLine_PortageMachine_Start 1;
  set DNAProductionLine_FluorescentMachine_HeartBeat 1;
  while (get DNAProductionLine_FluorescentMachine_HeartBeat < 30){
      set DNAProductionLine_PurificationMachine_Start 1;
      set DNAProductionLine_FluorescentMachine_Start 1;
  };

  set DNAProductionLine_PurificationMachine_Start 0;
  set DNAProductionLine_FluorescentMachine_Start 0;
  if (get DNAProductionLine_PurificationMachine_Start = 0){
      set HarmonyWasher_switch_on on;
  };
  `;

executeScript(testScript).catch(console.error);